<?php


namespace services\buss;

use common\helpers\DateHelper;
use common\helpers\RedisHelper;
use common\models\base\CommonStatus;
use common\models\base\Department;
use common\models\base\Project;
use common\models\buss\AccountsFans;
use common\models\buss\Devices;
use common\models\buss\Doctors;
use common\models\buss\Platform;
use common\models\buss\Accounts;
use common\models\member\Member;
use services\base\CommonStatusService;
use services\base\DepartmentService;
use services\log\LogMemberOpService;
use services\member\MemberService;
use Yii;
use common\components\Service;
use common\helpers\CommonHelper;

class AccountsService extends Service
{
    /**
     * 账号列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getList(array $params, int $page, int $pageSize): array
    {
        $query = Accounts::find()
            ->alias('a')
            ->select(['a.*', 'cs.name t_name', 'de.name login_device_name', 'af.fans_num', 'af.rate', 'd.name doctor_name'])
            ->leftJoin(CommonStatus::tableName() . ' cs', 'a.t_id = cs.id and cs.type = '. CommonStatus::TYPE_ACCOUNTS)
            ->leftJoin(Doctors::tableName() . ' d', 'd.id = a.doctor_id and d.status in ('.Doctors::STATUS_ENABLE.','. Doctors::STATUS_INVALID.')')
            ->leftJoin(Devices::tableName() . ' de', 'de.id = a.login_device_id and de.status in ('.Devices::STATUS_ENABLE.','. Devices::STATUS_INVALID.')')
            ->leftJoin(AccountsFans::tableName() . ' af', 'af.id = a.fans_id')
            ->where([
                'a.status' => [
                    Accounts::STATUS_ENABLE,
                    Accounts::STATUS_INVALID
                ],
//                'a.project_id' => array_column(MemberService::getAllProjectListCondition(), 'value')
            ]);

        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['a.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    [
                        'a.department_id' => $memberAuth['all_department_ids'],
                        'a.project_id' => $memberAuth['member_project_ids'],
                        'a.use_mid' => $memberAuth['all_member_ids'],
                    ]
                ]);
            } else {
                $query->andWhere([
                    'a.department_id' => $memberAuth['all_department_ids'],
                    'a.project_id' => $memberAuth['member_project_ids'],
                    'a.use_mid' => $memberAuth['all_member_ids'],
                ]);
            }
        }

        // 搜索账号昵称/手机号
        if (isset($params['keywords']) && $params['keywords']) {
            /*if (is_numeric($params['keywords'])) { // 账号被封了可能昵称显示为纯数字
                $query->andWhere(['like', 'a.login_account', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere(['like', 'a.nickname', $params['keywords']]);
            }*/
            $query->andWhere([
                'or',
                ['like', 'a.nickname', $params['keywords']],
                ['like', 'a.login_account', "{$params['keywords']}%", false],
                ['like', 'a.account_name', "{$params['keywords']}%", false]
            ]);
        }
        // 项目
        if (isset($params['project_id']) && $params['project_id']) {
            $query->andWhere(['a.project_id' => $params['project_id']]);
        }
        // 部门
        if (isset($params['department_id']) && $params['department_id']) {
            $allIds = $params['department_id'];
            $department = RedisHelper::getDepartment($params['department_id']);
            if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_ALL) {
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $allIds = array_merge([$department->id], array_column($childDepartmentList, 'id'));
            }
            $query->andWhere(['a.department_id' => $allIds]);
        }
        // 平台
        if (isset($params['platform_id']) && $params['platform_id']) {
            $query->andWhere(['a.platform_id' => $params['platform_id']]);
        }
        // 认证医生
        if (isset($params['doctor_id']) && $params['doctor_id']) {
            $query->andWhere(['a.doctor_id' => $params['doctor_id']]);
        }
        // 运营人
        if (isset($params['use_mid']) && $params['use_mid']) {
            $query->andWhere(['a.use_mid' => $params['use_mid']]);
        }
        // 状态
        if (isset($params['status']) && is_numeric($params['status'])) {
            $query->andWhere(['a.status' => $params['status']]);
        }
        // 是否投流
        if (isset($params['is_stream']) && is_numeric($params['is_stream'])) {
            $query->andWhere(['a.is_stream' => $params['is_stream']]);
        }

        $orderBy = [];
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'accounts_reg_date':
                    $orderBy['a.accounts_reg_date'] = $sort;
                    break;
                case 'fans_num':
                    $orderBy['af.fans_num'] = $sort;
                    break;
                default :
                    break;
            }
        }
        $orderBy['a.status'] = SORT_DESC;
        $orderBy['a.id'] = SORT_DESC;
        $list = $this->getListPageRes($query, $page, $pageSize, $orderBy);

        foreach ($list['list'] as &$val) {
            $platform = $val['platform_id'] ? RedisHelper::getPlatform($val['platform_id']) : '';
            $val['platform_name'] = $platform && $platform->status != Platform::STATUS_DELETE ? $platform->name : '';
            $project = $val['project_id'] ? RedisHelper::getProject($val['project_id']) : '';
            $val['project_name'] = $project && $project->status != Project::STATUS_DELETE ? $project->project_name : '';
//            $department = $val['department_id'] ? RedisHelper::getDepartment($val['department_id']) : '';
//            $val['department_name'] = $department && $department->status != Department::STATUS_DELETE ? $department->department_name : '';
            $departmentName = DepartmentService::getParent($val['department_id']);
            $val['department_name'] = implode(' / ', $departmentName);
            $member = $val['use_mid'] ? RedisHelper::getMember($val['use_mid']) : '';
            $val['use_mname'] = $member && $member->status != Member::STATUS_DELETE ? $member->realname : '';
            $val['created_at_str'] = DateHelper::timestampToDate($val['created_at']);
            $val['is_stream_str'] = Accounts::$streams[$val['is_stream']] ?? '';
            $val['status_name'] =  Accounts::$statuss[$val['status']] ?? '';
        }
        return $list;
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Accounts::STATUS_ENABLE, 'label' => Accounts::$statuss[Accounts::STATUS_ENABLE]],
            ['value' => Accounts::STATUS_INVALID, 'label' => Accounts::$statuss[Accounts::STATUS_INVALID]],
        ];
    }

    /**
     * 运营人下拉筛选项
     * @return array[]
     */
    public static function getPrincipalMemberCondition(): array
    {
        $query = Accounts::find()
            ->alias('a')
            ->select(['a.use_mid value', 'm.realname label'])
            ->innerJoin(Member::tableName() . ' m', 'a.use_mid = m.id')
            ->where(['a.status' => [Accounts::STATUS_ENABLE, Accounts::STATUS_INVALID]]);

        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['a.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    ['a.use_mid' => $memberAuth['all_member_ids']]
                ]);
            } else {
                $query->andWhere(['a.use_mid' => $memberAuth['all_member_ids']]);
            }
        }
        return $query->groupBy('a.use_mid')
            ->asArray()
            ->all();
    }

    /**
     * 根据医生ID查找绑定正常账号
     * @param int $doctorId
     * @return Accounts[]
     */
    public static function getEnableListByDoctorId(int $doctorId): array
    {
        return Accounts::find()
            ->alias('a')
            ->select(['a.*', 'pf.name platform_name'])
            ->leftJoin(Platform::tableName() . ' pf', 'pf.id = a.platform_id')
            ->where([
                'a.doctor_id' => $doctorId,
                'a.status' => Accounts::STATUS_ENABLE,
            ])
            ->asArray()
            ->all();
    }

    /**
     * 获取正常列表下拉筛选
     * @param int $doctorId
     * @return array
     */
    public static function getEnableConditionList(int $doctorId): array
    {
        $accounts = self::getEnableListByDoctorId($doctorId);
        $data = [];
        foreach ($accounts as $account) {
            $data[] = [
                'value' => $account['id'],
                'label' => $account['platform_name'] ? $account['platform_name'] .'-'. $account['nickname'] : $account['nickname'] ,
            ];
        }
        return $data;
    }

    /**
     * 根据平台ID查找绑定正常账号
     * @param int|null $platformId
     * @param int|array|null $orIds
     * @return array
     */
    public static function getEnableListByPlatformId(?int $platformId, $orIds = null): array
    {
        $projectIds = array_column(MemberService::getProjectEditCondition(), 'value');
        $query = Accounts::find()
            ->where([
                'project_id' => $projectIds,
                'status' => Accounts::STATUS_ENABLE,
            ]);
        if (!is_null($platformId)) {
            $query->andWhere(['platform_id' => $platformId]);
        }
        if ($orIds) {
            $query->orWhere([
                'id' => $orIds,
                'status' => [Accounts::STATUS_INVALID, Accounts::STATUS_ENABLE]
            ]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 根据是否投流查找绑定正常账号
     * @param int $steam
     * @param int|array|null $orIds
     * @return Accounts[]
     */
    public static function getEnableListBySteam(int $steam, $orIds = null): array
    {
        $query = Accounts::find()
            ->where([
                'is_stream' => $steam,
                'status' => Accounts::STATUS_ENABLE,
            ]);
        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    [
                        'department_id' => $memberAuth['all_department_ids'],
                        'project_id' => $memberAuth['member_project_ids'],
                        'use_mid' => $memberAuth['all_member_ids'],
                    ]
                ]);
            } else {
                $query->andWhere([
                    'department_id' => $memberAuth['all_department_ids'],
                    'project_id' => $memberAuth['member_project_ids'],
                    'use_mid' => $memberAuth['all_member_ids'],
                ]);
            }
        }
        if ($orIds) {
            $query->orWhere([
                'id' => $orIds,
                'status' => [Accounts::STATUS_INVALID, Accounts::STATUS_ENABLE]
            ]);
        }
        return $query->asArray()
            ->all();
    }

    /**
     * 获取编辑筛选项
     * @param int|null $platformId
     * @param array|int|null $orIds
     * @return array
     */
    public static function getEditCondition(?int $platformId, $orIds = null): array
    {
        return CommonHelper::getListCondition(self::getEnableListByPlatformId($platformId, $orIds), ['value_column' => 'id', 'label_column' => 'nickname']);
    }

    /**
     * 获取对标账号编辑筛选项
     * @param int|null $platformId
     * @param $orIds
     * @return array
     */
    public function getEnableList(?int $platformId, $orIds = null): array
    {
        $projectIds = array_column(MemberService::getProjectEditCondition(), 'value');
        $query = Accounts::find()
            ->alias('a')
            ->select(['a.*', 'p.name platform_name'])
            ->leftJoin(Platform::tableName() . ' p', 'a.platform_id = p.id')
            ->where([
                'a.project_id' => $projectIds,
                'a.status' => Accounts::STATUS_ENABLE,
            ]);
        if (!is_null($platformId)) {
            $query->andWhere(['a.platform_id' => $platformId]);
        }
        if ($orIds) {
            $query->orWhere([
                'a.id' => $orIds,
                'a.status' => [Accounts::STATUS_INVALID, Accounts::STATUS_ENABLE]
            ]);
        }
        $list = $query->orderBy(['a.id' => SORT_ASC])->asArray()->all();
        $data = [];
        foreach ($list as $row) {
            $data[] = [
                'value' => $row['id'],
                'label' => $row['platform_name'] ? $row['nickname'] .'-'. $row['platform_name'] : $row['nickname'],
            ];
        }
        return $data;
    }

    /**
     * 账号详情
     * @param int $id
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        // 内容信息
        $accounts = Accounts::findOne($id);
        if ($accounts) {
            $data = [
                'id' => $accounts->id,
                'department_id' => $accounts->department_id,
                'project_id' => $accounts->project_id,
                'platform_id' => $accounts->platform_id,
                'account_name' => $accounts->account_name,
                'nickname' => $accounts->nickname,
                't_id' => $accounts->t_id,
                'doctor_id' => $accounts->doctor_id,
                'login_device_id' => $accounts->login_device_id,
                'is_stream' => $accounts->is_stream,
                'login_account' => $accounts->login_account,
                'login_passwd' => $accounts->login_passwd,
                'use_mid' => $accounts->use_mid,
                'accounts_reg_date' => $accounts->accounts_reg_date,
                'status' => $accounts->status,
            ];
        }
        $condition = [
            'project' => MemberService::getProjectEditCondition($data['project_id'] ?? null),
            'platform' => PlatformService::getEditCondition($data['platform_id'] ?? null),
            'account_type' => CommonStatusService::getEditCondition(CommonStatus::TYPE_ACCOUNTS, $data['t_id'] ?? null),
            'principal_member' => $accounts ? MemberService::getMemberByProject($data['project_id'] ?? null, $data['department_id'] ?? null, $data['use_mid']) : [],
            'doctor' => $accounts ? DoctorsService::getProjectEditCondition($data['project_id'], $data['doctor_id']) : [],
            'device' => DevicesService::getEditCondition($data['login_device_id'] ?? null),
            'department_arr' => MemberService::getMemberDepartmentCondition()['list'],
        ];
        if ($accounts) {
            if (in_array($data['project_id'], array_column($condition['project'], 'value')) === false) {
                $data['project_id'] = 0;
            }
            if (in_array($data['platform_id'], array_column($condition['platform'], 'value')) === false) {
                $data['platform_id'] = 0;
            }
            if (in_array($data['t_id'], array_column($condition['account_type'], 'value')) === false) {
                $data['t_id'] = 0;
            }
            if (in_array($data['use_mid'], array_column($condition['principal_member'], 'value')) === false) {
                $data['use_mid'] = 0;
            }
            if (in_array($data['doctor_id'], array_column($condition['doctor'], 'value')) === false) {
                $data['doctor_id'] = 0;
            }
            if (in_array($data['login_device_id'], array_column($condition['device'], 'value')) === false) {
                $data['login_device_id'] = 0;
            }
        }
        return array_merge($data, ['condition' => $condition]);
    }

    /**
     * 更新账号
     * @throws \Exception
     */
    public function updateAccounts(array $params): array
    {
        $account = new Accounts();
        // 是否为编辑，编辑判断排除当前ID
        $whereId = [];
        $scenario = 'create';
        $oldAccount = null;
        if ($params['id']) {
            $whereId = ['!=', 'id', $params['id']];
            // 账号表
            $oldAccount = self::getData($params['id']);
            $account = Accounts::findOne($params['id']);
            $scenario = 'edit';
        }
        // 判断昵称是否存在
        $check = Accounts::find()
            ->select(['id'])
            ->where([
                'nickname' => $params['nickname'],
                'platform_id' => $params['platform_id'],
                'project_id' => $params['project_id'],
                'status' => Accounts::STATUS_ENABLE
            ])
            ->andWhere($whereId)
            ->asArray()
            ->one();
        if ($check) {
            return CommonHelper::api(422, '账号已存在');
        }

        $account->platform_id = $params['platform_id'];
        $account->account_name = $params['account_name'] ?? '';
        $account->nickname = $params['nickname'];
        $account->t_id = $params['t_id'] ?? '';
        $account->doctor_id = $params['doctor_id'] ?? 0;
        $account->login_device_id = $params['login_device_id'] ?? 0;
        $account->is_stream = $params['is_stream'];
        $account->login_account = $params['login_account'] ?? '';
        $account->login_passwd = $params['login_passwd'];
        $account->project_id = $params['project_id'];
        $account->department_id = $params['department_id'];
        $account->use_mid = isset($params['use_mid']) && $params['use_mid'] ? $params['use_mid'] : 0;
        $account->status = $params['status'] ?? Accounts::STATUS_ENABLE;
        $account->operation_id = Yii::$app->user->identity->member_id;
        $account->operation_name = Yii::$app->user->identity->member->realname;
        $account->accounts_reg_date = $params['accounts_reg_date'];
        $account->saveAndCheckResult();

        // 添加日志
        LogMemberOpService::createAccountLog($scenario, $account, $oldAccount);
        return ['id' => $account->id];
    }

    /**
     * 账号数据
     * @param int $id
     * @return Accounts|null
     */
    public static function getData(int $id): ?Accounts
    {
        return Accounts::findOne($id);
    }

    /**
     * 账号删除
     * @throws \Exception
     */
    public function deleteAccounts(array $params): array
    {
        // 更新账号状态为-1
        Accounts::updateAll([
            'status' => Accounts::STATUS_DELETE,
            'operation_id' => Yii::$app->user->identity->member_id,
            'operation_name' => Yii::$app->user->identity->member->realname,
            'updated_at' => time()
        ], ['id' => $params['id']]);

        // 添加日志
        LogMemberOpService::createAccountLog('delete', self::getData($params['id']));
        return ['id' => $params['id']];
    }

    /**
     * 设置运营人
     * @param array $params
     * @return array
     * @throws \Exception
     */
    public function setPrincipal(array $params): array
    {
        $accountArr = is_array($params['ids']) ? $params['ids'] : explode(',', $params['ids']);

        $updateNum = Accounts::updateAll([
            'department_id' => $params['department_id'],
            'use_mid' => $params['use_mid'],
            'updated_at' => time()
        ], ['id' => $accountArr]);

        // 日志
        $new = new Accounts();
        $new->id = 0;
        $accountNameArr = Accounts::find()->select(['nickname'])->where(['id' => $accountArr])->asArray()->column();
        $new->nickname = implode('/', $accountNameArr);
        $new->use_mid = $params['use_mid'];
        LogMemberOpService::createAccountLog('update_principal', $new);

        return [
            'update_num' => $updateNum,// 已修改
        ];
    }

    /**
     * 人员删除部门解除绑定人员数据
     * @param int $memberId
     * @param $departmentIds
     * @return void
     */
    public static function clearUseMid(int $memberId, $departmentIds): void
    {
        Accounts::updateAll(['use_mid' => 0], ['department_id' => $departmentIds, 'use_mid' => $memberId]);

    }

    /**
     * 根据项目统计账号数
     * @param $projectIds
     * @return array
     */
    public static function getStaticsNumByProject($projectIds): array
    {
        return Accounts::find()
            ->select(['project_id', 'COUNT(*) account_num'])
            ->where([
                'project_id' => $projectIds,
            ])
            ->andWhere(['!=', 'status', Accounts::STATUS_DELETE])
            ->indexBy('project_id')
            ->groupBy('project_id')
            ->asArray()
            ->all();
    }
}
